﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection.PortableExecutable;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace SuperKit
{
    /// <summary>
    /// EHantaiWindow.xaml 的交互逻辑
    /// </summary>
    public partial class HtmlWindow : Window {
        CancellationTokenSource canceller = new CancellationTokenSource();
        private List<string> urls;

        public HtmlWindow() {
            InitializeComponent();
        }


        private void OpenMain_Click(object sender, RoutedEventArgs e) {
            MainWindow mainWindow = new MainWindow();
            mainWindow.Show();
        }

        private void Settings_Click(object sender, RoutedEventArgs e) {
            SettingsWindow settingsWindow = new SettingsWindow();
            settingsWindow.ShowDialog();
        }

        private void Exit_Click(object sender, RoutedEventArgs e) {
            Close();
        }

        private void buttonClear_Click(object sender, RoutedEventArgs e) {
            txtSource.Text = "";
        }

        private void PickUrls() {
            urls = new List<string>();
            StringReader s = new StringReader(txtUrl.Text);
            while (true) {
                string line = s.ReadLine();
                if (line == null) {
                    break;
                }
                urls.Add(line.Replace("https", "http", StringComparison.OrdinalIgnoreCase));
            }
        }

        private void buttonGo_Click(object sender, RoutedEventArgs e) {
            PickUrls();
            Task.Factory.StartNew(GetEHentaiUrl, canceller.Token);
        }

        private void buttonSukebeiGo_Click(object sender, RoutedEventArgs e) {
            PickUrls();
            Task.Factory.StartNew(GetSukebeiUrl, canceller.Token);
        }


        private void Flush(string text) {
            Dispatcher.Invoke(() => {
                txtSource.AppendText(text);
                txtSource.AppendText("\r\n");
            });
        }

        private void LogStatus(string text) {
            Dispatcher.Invoke(() => {
                labelStatus.Content = text;
            });
        }

        private void LogItems(int current, int max) {
            LogItems($"载入: {current} / {max}");
        }

        private void LogItems(string text) {
            Dispatcher.Invoke(() => {
                labelItems.Content = text;
            });
        }

        private void LogUrls(string text) {
            Dispatcher.Invoke(() => {
                labelUrls.Content = text;
            });
        }

        private void GetSukebeiUrl() {
            WebClient client = new WebClient();

            int urlCount = 1;
            foreach (var url in urls) {
                LogUrls($"主要URL:{urlCount++}/{urls.Count}");
                LogStatus("解析主URL...");
                LogItems("-/-");
                string html = string.Empty;
                try {
                    html = client.DownloadString(url);
                } catch (WebException ex) {
                    Flush(ex.Message);
                    return;
                }

                string HEADER = "magnet:?xt=urn:btih:";
                string END = "\"";
                string DISCARD_MARK = ")";
                string ESCAPE_1 = "&amp;";

                List<string> items = new List<string>();
                int pointer = 0;
                while (true) {
                    int index = html.IndexOf(HEADER, pointer);
                    if (index == -1) {
                        break;
                    }

                    int end = html.IndexOf(END, index);
                    if (end == -1) {
                        break;
                    }

                    string item = html[index..end];
                    if (item.Contains(DISCARD_MARK) == false) {
                        item = item.Replace(ESCAPE_1, "&");
                        items.Add(item);
                        Flush(item);
                    }

                    pointer = end + 1;
                }
            }



            LogStatus("载入完成！");
        }

        private void GetEHentaiUrl() {            
            WebClient client = new WebClient();

            int urlCount = 1;
            foreach (var url in urls) {
                LogUrls($"主要URL:{urlCount++}/{urls.Count}");
                LogStatus("解析主URL...");
                LogItems("-/-");
                string response = string.Empty;
                try {
                    response = client.DownloadString(url);
                } catch (WebException ex) {
                    Flush(ex.Message);
                    return;
                }

                List<string> items = GetHtmlItems(response);

                LogStatus("解析种子URL...");
                LogItems(0, items.Count);

                int MAX = 99999;
                int count = 0;
                foreach (var item in items) {
                    try {
                        response = client.DownloadString(item);
                    } catch (WebException ex) {
                        Flush(ex.Message);
                        return;
                    }

                    SetTitlePath(GetTitle(response));

                    var torrents = GetTorrentItems(response);
                    var downloads = GetDownloadItems(response);
                    if (torrents.Count == 0) {
                        continue;
                    }

                    var best = GetBest(torrents, downloads);
                    Flush(best);
                    //for (int i = 0; i < torrents.Count; i++) {
                    //Flush($"DownLoad:{downloads[i]}, Url:{torrents[i]}");
                    //}

                    count++;
                    LogItems(count, items.Count);
                    if (count >= MAX) {
                        break;
                    }

                }
            }


            LogStatus("载入完成！");
        }

        private string GetTitle(string response) {
            string HEADER = "<title>Torrents for";
            int index = response.IndexOf(HEADER, StringComparison.OrdinalIgnoreCase);
            if (index == -1) {
                return string.Empty;
            }
            int end = response.IndexOf("E-Hentai Galleries</title>", StringComparison.OrdinalIgnoreCase);
            if (end == -1) {
                return string.Empty;
            }
            string title = response[(index + HEADER.Length)..end].Trim();
            return title;
        }

        private void SetTitlePath(string value) {
            if (Kit.IsEmpty(value)) {
                return;
            }
            Dispatcher.Invoke(() => {
                txtTitlePath.Text = $"G:\\COSPLAY\\{value}";;
            });
        }

        private string GetBest(List<string> torrents, List<int> downloads) {
            var best = torrents[0];
            var best_download = downloads[0];
            for (int i = 0; i < torrents.Count; i++) {
                if (downloads[i] > best_download) {
                    best = torrents[i];
                    best_download = downloads[i];
                }
            }
            return best;
        }

        private List<string> GetHtmlItems(string html) {
            string HEADER = "https://e-hentai.org/gallerytorrents";
            string END = "\"";
            string DISCARD_MARK = ")";
            string ESCAPE_1 = "&amp;";

            List<string> items = new List<string>();
            int pointer = 0;
            while (true) {
                int index = html.IndexOf(HEADER, pointer);
                if (index == -1) {
                    break;
                }

                int end = html.IndexOf(END, index);
                if (end == -1) {
                    break;
                }

                string item = html[index..end];
                if (item.Contains(DISCARD_MARK) == false) {
                    item = item.Replace(ESCAPE_1, "&");
                    items.Add(item);
                }


                pointer = end + 1;
            }

            return items;
        }

        private List<string> GetTorrentItems(string html) {
            string HEADER = "https://ehtracker.org/get/";
            string END = "\"";
            string DISCARD_MARK = "return false";
            string ESCAPE_1 = "&amp;";

            List<string> items = new List<string>();
            int pointer = 0;
            while (true) {
                int index = html.IndexOf(HEADER, pointer);
                if (index == -1) {
                    break;
                }

                int end = html.IndexOf(END, index);
                if (end == -1) {
                    break;
                }

                string item = html[index..end];
                if (item.Contains(DISCARD_MARK) == false) {
                    item = item.Replace(ESCAPE_1, "&");
                    items.Add(item);
                }


                pointer = end + 1;
            }

            return items;
        }

        private List<int> GetDownloadItems(string html) {
            string HEADER = "Downloads:</span> ";
            string END = "</td>";

            List<int> items = new List<int>();
            int pointer = 0;
            while (true) {
                int index = html.IndexOf(HEADER, pointer);
                if (index == -1) {
                    break;
                }

                int end = html.IndexOf(END, index);
                if (end == -1) {
                    break;
                }

                var item = html[(index + HEADER.Length)..end];
                items.Add(Kit.ParseInt(item));

                pointer = end + 1;
            }

            return items;
        }

    }
}
